package com.naiterui.ehp.bs.esign.service.impl;


import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.esign.DigitalCertificateBO;
import com.naiterui.ehp.bp.bo.esign.EsignDoctorBO;
import com.naiterui.ehp.bp.bo.esign.EsignNoSecretBO;
import com.naiterui.ehp.bp.bo.esign.NoSecretParamBO;
import com.naiterui.ehp.bp.bo.esign.PreSignResultBO;
import com.naiterui.ehp.bp.bo.esign.WillTypeBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.constants.EsignServiceProviderEnum;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.encypt.AESUtil;
import com.naiterui.ehp.bp.utils.encypt.MD5;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.esign.api.ISignService;
import com.naiterui.ehp.bs.esign.api.bjca.vo.SignFileUploadVO;
import com.naiterui.ehp.bs.esign.api.bjca.vo.SignUserParamVO;
import com.naiterui.ehp.bs.esign.api.scca.entity.EsignSccaCert;
import com.naiterui.ehp.bs.esign.api.scca.repository.IEsignSccaCertRepository;
import com.naiterui.ehp.bs.esign.api.vo.SignAccountVO;
import com.naiterui.ehp.bs.esign.api.vo.SignUserInfoVO;
import com.naiterui.ehp.bs.esign.api.vo.UserInfoParamVO;
import com.naiterui.ehp.bs.esign.entity.mysql.EsignDoctor;
import com.naiterui.ehp.bs.esign.entity.mysql.EsignNoSecret;
import com.naiterui.ehp.bs.esign.entity.mysql.EsignPharmacist;
import com.naiterui.ehp.bs.esign.exception.ExceptionCodes;
import com.naiterui.ehp.bs.esign.feign.IDoctorFeignClient;
import com.naiterui.ehp.bs.esign.repository.mysql.IEsignRecomEsignDoctorRepository;
import com.naiterui.ehp.bs.esign.repository.mysql.IEsignRecomEsignPharmacistRepository;
import com.naiterui.ehp.bs.esign.service.IDoctorService;
import com.naiterui.ehp.bs.esign.service.IEsignService;
import com.naiterui.ehp.bs.esign.service.INoSecretService;
import com.naiterui.ehp.bs.esign.utils.Constants;
import com.naiterui.ehp.bs.esign.utils.EsignWillTypeEnum;
import com.naiterui.ehp.bs.esign.utils.SealImageUtil;
import com.naiterui.ehp.bs.esign.utils.SignUtils;
import com.naiterui.ehp.bs.esign.vo.esign.PreSignResultVO;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description 医生签名信息
 * @Author gongbaoqiang
 * @Date 2020/1/2 10:44 AM
 */
@Slf4j
@Service
public class EsignDoctorServiceImpl implements IDoctorService {

    @Autowired
    private ISignService signService;

    @Autowired
    private IEsignRecomEsignDoctorRepository recomEsignDoctorRepository;

    @Autowired
    private IEsignRecomEsignPharmacistRepository recomEsignPharmacistRepository;

    @Autowired
    private IDoctorFeignClient doctorFeignClient;

    @Autowired
    private IEsignService esignService;

    @Autowired
    private IEsignSccaCertRepository esignSccaCertRepository;

    @Value("${naiterui.image.basePath}")
    private String basePath;

    @Autowired
    private INoSecretService noSecretService;

    @Value("${file.base.prefix}")
    private String fileBasePrefix;
    @Value("${naiterui.scca-risk-warning-notice}")
    private String informPath;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public EsignDoctor addUserDr(SignUserParamVO userParamVO) throws BusinessException {
        boolean update = true;
        // 签名注册用户入库
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByIdCard(userParamVO.getIdCard());

        if (doctor == null) {
            doctor = new EsignDoctor();
            doctor.setAuthStatus(EsignDoctor.AUTH_STATUS_PASS);
            doctor.setCreatedAt(new Date());
            update = false;
        }

        UserInfoParamVO userInfoParamVO = UserInfoParamVO.builder()
                .idNo(userParamVO.getIdCard())
                .name(userParamVO.getName())
                .phone(userParamVO.getPhone())
                .organ(userParamVO.getHospital())
                .cerType(UserInfoParamVO.CER_TYPE_IDCARD)
                .title(Constants.USER_TITLE_DR)
                .sealFlag(false)
                .pin(userParamVO.getPwd())
                .build();
        SignUserInfoVO userInfoVO = null;
        if (doctor.getOpenId() == null) {
            userInfoVO = signService.registAccount(userInfoParamVO);
        } else {
            userInfoParamVO.setOpenId(doctor.getOpenId());
            userInfoVO = signService.updateAccount(userInfoParamVO);
        }
        doctor.setOpenId(userInfoVO.getOpenId());
        doctor.setDoctorId(userParamVO.getUserId());
        doctor.setName(userParamVO.getName());
        doctor.setIdCard(userParamVO.getIdCard());
        doctor.setPhone(userParamVO.getPhone());
        String sealImagePath = userParamVO.getSealImagePath();

        doctor.setSealImage(SealImageUtil.setSealImage(sealImagePath));
        doctor.setNoSecret(null == doctor.getNoSecret() ? 0 : doctor.getNoSecret());
        doctor.setChangedAt(new Date());
        if (update) {
            recomEsignDoctorRepository.update(doctor);
        } else {
            recomEsignDoctorRepository.save(doctor);
        }

        return doctor;
    }

    @Override
    public void updatePhone(Long doctorId, String phone) throws BusinessException {
        // 签名注册用户入库
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if(doctor == null){
            return ;
        }
        signService.updateAccount(UserInfoParamVO.builder()
                .openId(doctor.getOpenId())
                .phone(phone)
                .sealFlag(false)
                .build());
        doctor.setPhone(phone);
        doctor.setChangedAt(new Date());
        recomEsignDoctorRepository.update(doctor);
    }


    @Override
    public String getRealnameCode(String name, String phone, String idCard) throws BusinessException {
        // EsignDoctor doctor = recomEsignDoctorRepository.findFirstByPhone(phone);
        // if (doctor == null) {
        // throw new BusinessException(ExceptionCodes.ESIGN_DOCTOR_NOT_RECORDED);
        // }
        EsignPharmacist esignPharmacist =
            recomEsignPharmacistRepository.findFirstByIdCardAndAuthStatus(idCard, EsignPharmacist.AUTH_STATUS_PASS);
        if (esignPharmacist != null) {
            throw new BusinessException(ExceptionCodes.ESIGN_AUTH_IDCARD_EXISTS);
        }
        return signService.getRealnameCode(name, phone, idCard);
    }

    @Override
    public boolean checkRealname(String phone, String code) throws BusinessException {
        //重复提交实名的同样回写实名状态
        signService.checkRealnameCode(phone, code);
        this.setRealnameStatusByPhone(phone);
        return true;
    }

    /**
     * 设置实名通过
     *
     * @param phone
     * @throws BusinessException
     */
    public void setRealnameStatusByPhone(String phone) throws BusinessException {
        SignUserParamVO signUserParamVO = doctorFeignClient.getUserByPhone(phone);
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByDoctorIdAndIdCard(signUserParamVO.getUserId(),
            signUserParamVO.getIdCard());
        if (null != doctor) {
            this.setRealnameStatus(doctor);
        } else {
            addUserDr(signUserParamVO);
        }
        // EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByPhone(phone);
        // this.setRealnameStatus(esignDoctor);
    }


    /**
     * 设置实名通过
     *
     * @param doctorId
     * @throws BusinessException
     */
    public void setRealnameStatusByDoctorId(Long doctorId) throws BusinessException {
        EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        this.setRealnameStatus(esignDoctor);
    }

    /**
     * 设置实名通过
     *
     * @param esignDoctor
     * @throws BusinessException
     */
    private void setRealnameStatus(EsignDoctor esignDoctor) throws BusinessException {
        int auditStatus = EsignDoctor.AUTH_STATUS_PASS;
        esignDoctor.setAuthStatus(auditStatus);
        esignDoctor.setChangedAt(new Date());
        recomEsignDoctorRepository.update(esignDoctor);
        // 医生签名回调(userId, status, reason),通过回调方式处理，是为了保证流程统一
        doctorFeignClient.esignAuth(esignDoctor.getDoctorId(), auditStatus, "成功");
    }

    @Override
    public EsignDoctorBO getEsignInfo(Long doctorId) throws BusinessException {
        EsignDoctorBO bo = new EsignDoctorBO();
        EsignDoctor doctor = this.getEsignDoctor(doctorId);
        BeanUtil.copyProperties(doctor, bo);
        bo.setSealImage(ConfigUtil.getString("ehp.domain.img") + bo.getSealImage());
        return bo;
    }

    @Override
    public List<WillTypeBO> getWillTypes(Long doctorId) throws BusinessException {
        EsignDoctor doctor = this.getEsignDoctor(doctorId);
        // 未设置密码移除掉，密码签署方式
        Boolean signPwdSet = RedisUtil.keyOps().existsKey(Constants.ESIGN_PWD_CACHE_NEWEST + doctor.getPhone());
        List<WillTypeBO> willTypes = esignService.getWillTypes(doctor.getWillType());
        if(!signPwdSet){
            // 只移除E签宝密码签署方式(四川CA目前只有密码暂不移除)
            willTypes.removeIf(w -> EsignWillTypeEnum.WUKONG_SIGN_PWD.getValue().equals(w.getValue()));
        }
        return willTypes;
    }

    @Override
    public void updateWillType(Long doctorId, String willType) throws BusinessException{
        EsignDoctor doctor = this.getEsignDoctor(doctorId);
        doctor.setWillType(willType);
        doctor.setChangedAt(new Date());
        recomEsignDoctorRepository.update(doctor);
    }

    @Override
    public void updateSignPassword(Long doctorId, String password) throws BusinessException {
        EsignDoctor doctor = this.getEsignDoctor(doctorId);
        String phone = doctor.getPhone();
        String md5Pwd = MD5.md5(password);
        String lastedPwd = RedisUtil.valueOps().getString(Constants.ESIGN_PWD_CACHE_LASTED + phone);
        //密码与上次一致，则不向签名服务同步
        if (md5Pwd.equals(lastedPwd)) {
            return;
        }
        //存储签名密码
        doctor.setAuthPwd(AESUtil.encrypt(CommonConstant.ESIGN_NO_SECRET_KEY, password));
        this.recomEsignDoctorRepository.update(doctor);
        RedisUtil.valueOps().setString(Constants.ESIGN_PWD_CACHE_PRE + phone, md5Pwd);
        RedisUtil.valueOps().setString(Constants.ESIGN_PWD_CACHE_NEWEST + phone, md5Pwd);
        RedisUtil.valueOps().setString(Constants.ESIGN_PWD_CACHE_LASTED + phone, md5Pwd);
        // 同步厂商接口(如果支持)
        signService.resetSignPwd(doctor.getOpenId(), password);

        // 获取激活厂商
        EsignServiceProviderEnum service = signService.getCurrentServiceProvider();
        if (EsignServiceProviderEnum.SCCA.equals(service)) {
            log.info("设置密码-四川CA设置密码触发实名 doctorId:{}", doctorId);
            // 四川CA设置密码时同时设置实名状态
            this.setRealnameStatusByDoctorId(doctorId);
        }
    }


    private EsignDoctor getEsignDoctor(Long doctorId) throws BusinessException{
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (doctor == null) {
            log.info("医师签名账号不存在: doctorId={}", doctorId);
            throw  new BusinessException(ExceptionCodes.ESIGN_DOCTOR_USER_NOT_EXISTS);
        }
        return doctor;
    }

    /**
     * <pre>
     *     获取用户openId
     * </pre>
     *
     * @return
     *
     * @throws BusinessException
     */
    @Override
    public SignAccountVO getSignAccount(Long doctorId, String unionId) throws BusinessException {

        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (doctor == null || !EsignDoctor.AUTH_STATUS_PASS.equals(doctor.getAuthStatus())) {
            throw new BusinessException(ExceptionCodes.ESIGN_REALNAME_NOT_AUTH);
        }
        String openId = Optional.ofNullable(doctor).map(EsignDoctor::getOpenId).orElse(null);
        String sealImage = Optional.ofNullable(doctor).map(EsignDoctor::getSealImage).orElse(null);

        if (StringUtils.isBlank(openId)) {
            log.warn("电子签名用户不存在，或三方用户标识不存在  signUserId:{}", doctorId);
            throw new BusinessException(ExceptionCodes.ESIGN_USER_SYNC_FAILED);
        }

        //预置签名
        String sealData = null;
        if (StringUtils.isNotBlank(sealImage)) {
            sealData = SignUtils.encodeBase64File(basePath + sealImage);
        }

        return SignAccountVO.builder()
                .openId(openId)
                .sealImage(Optional.ofNullable(doctor).map(EsignDoctor::getSealImage).orElse(null))
                .sealData(sealData)
                .requestFrom(SignAccountVO.REQUEST_FROM_APP)
                .willType(doctor.getWillType())
                .name(doctor.getName())
                .phone(doctor.getPhone())
                .idNo(doctor.getIdCard())
                .bizId(unionId)
                .userType(Constants.USER_TITLE_DR)
                .build();
    }

    @Override
    public Integer getNoSecretByDoctorId(Long doctorId) throws BusinessException {
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (doctor == null) {
            log.info("医师签名账号不存在: doctorId={}", doctorId);
            throw  new BusinessException(ExceptionCodes.ESIGN_DOCTOR_USER_NOT_EXISTS);
        }
        return Optional.ofNullable(doctor.getNoSecret()).orElse(0);
    }

    @Override
    public EsignNoSecretBO getEsignNoSecretByDoctorId(Long doctorId) throws BusinessException {
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (doctor == null) {
            log.info("医师签名账号不存在: doctorId={}", doctorId);
            throw  new BusinessException(ExceptionCodes.ESIGN_DOCTOR_USER_NOT_EXISTS);
        }
        Integer noSecret = Optional.ofNullable(doctor.getNoSecret()).orElse(0);
        boolean b = true;
        if(noSecret==0){
            b = false;
        }
        return EsignNoSecretBO.builder().pin(doctor.getAuthPwd()).noSecret(b).build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PreSignResultBO preNoSecret(Long doctorId) throws BusinessException {
        EsignNoSecret esignNoSecret = noSecretService.saveEsignNoSecret(doctorId, 0);
        String bizSn = esignNoSecret.getId().toString();
        return this.preSignRecipelDr(doctorId, bizSn);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setNoSecret(NoSecretParamBO paramBO) throws BusinessException {
        // 获取激活厂商
        EsignServiceProviderEnum service = signService.getCurrentServiceProvider();
        if (EsignServiceProviderEnum.SCCA.equals(service)) {
            if (paramBO.getNoSecret() && StringUtils.isBlank(paramBO.getAuthPwd())) {
                throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
            }
        }
        EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByDoctorId(paramBO.getSignUserId());
        if (esignDoctor == null) {
            log.info("医师签名账号不存在: doctorId={}", paramBO.getSignUserId());
            throw  new BusinessException(ExceptionCodes.ESIGN_DOCTOR_USER_NOT_EXISTS);
        }
        if (!paramBO.getNoSecret()) {
            recomEsignDoctorRepository.updateNoSecretAuthPwd(0, esignDoctor.getAuthPwd(), esignDoctor.getId());
            return;
        }
        // this.signDr(doctorId, authPwd);
        this.signDrNoSecret(paramBO);
        if (StringUtils.isNotBlank(paramBO.getAuthPwd())) {
            esignDoctor.setAuthPwd(AESUtil.encrypt(CommonConstant.ESIGN_NO_SECRET_KEY, paramBO.getAuthPwd()));
        }
        recomEsignDoctorRepository.updateNoSecretAuthPwd(1, esignDoctor.getAuthPwd(), esignDoctor.getId());
    }

    /**
     * 医师免密签名
     * @param doctorId 医生Id
     * @param pin 密码
     * @throws BusinessException
     */
    private void signDr(Long doctorId, String pin) throws BusinessException {
        EsignNoSecret esignNoSecret = noSecretService.saveEsignNoSecret(doctorId, 0);
        String bizSn = esignNoSecret.getId().toString();
        PreSignResultBO preSignResultBO = this.preSignRecipelDr(doctorId, bizSn);
        ISignService.SealPosVO sealPosVO = signService.getSealPosConfig().getNsPosDr();
        // e签宝在此处上传文件并设置签章位置
        SignFileUploadVO signFileUploadVO =
            noSecretService.getSignFileUploadVO(doctorId, bizSn, fileBasePrefix + informPath,
                SignFileUploadVO.USER_TYPE_DR, sealPosVO.getX(), sealPosVO.getY(), esignNoSecret.getCreatedAt());
        signFileUploadVO.setKeyword(sealPosVO.getKeyword());
        SignAccountVO signAccountVO = this.getSignAccount(doctorId, preSignResultBO.getUniqueId());
        signAccountVO.setPin(pin);
        signAccountVO.setRequestFrom(SignAccountVO.REQUEST_FROM_PC);
        esignService.sign(signFileUploadVO, signAccountVO);
    }

    /**
     * 医师开通免密签署
     * 
     * @param paramBO
     * @throws BusinessException
     */
    private void signDrNoSecret(NoSecretParamBO paramBO) throws BusinessException {
        String bizSn = noSecretService.getNoSecretBizSn(paramBO.getSignUserId(), 0);
        ISignService.SealPosVO sealPosVO = signService.getSealPosConfig().getNsPosDr();
        // e签宝在此处上传文件并设置签章位置
        SignFileUploadVO signFileUploadVO = noSecretService.getSignFileUploadVO(paramBO.getSignUserId(), bizSn,
            fileBasePrefix + informPath, SignFileUploadVO.USER_TYPE_DR, sealPosVO.getX(), sealPosVO.getY(), new Date());
        signFileUploadVO.setKeyword(sealPosVO.getKeyword());
        SignAccountVO signAccountVO = this.getSignAccount(paramBO.getSignUserId(), paramBO.getUniqueId());
        signAccountVO.setPin(paramBO.getAuthPwd());
        signAccountVO.setRequestFrom(SignAccountVO.REQUEST_FROM_PC);
        esignService.sign(signFileUploadVO, signAccountVO);
    }

    /**
     * 医生签名预签署
     * @param userId
     * @param bizSn
     * @return
     * @throws BusinessException
     */
    private PreSignResultBO preSignRecipelDr(Long userId, String bizSn) throws BusinessException {
        //BJCA在此处上传文件并设置签章位置,坐标和关键字不可同时设置
        SignFileUploadVO signFileUploadVO = noSecretService.getSignFileUploadVO(userId, bizSn, fileBasePrefix + informPath, SignFileUploadVO.USER_TYPE_DR, 525f, 105f, null);
        SignAccountVO signAccountVO = this.getSignAccount(userId, "");
        PreSignResultVO vo = esignService.preSignPdf(signFileUploadVO, signAccountVO);
        return PreSignResultBO.builder()
                .uniqueId(vo.getUniqueId())
                .faceUrl(vo.getUrl())
                .build();
    }

    @Override
    public void saveSealImg(Long doctorId, String sealImgPath) throws BusinessException {
        EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (null != esignDoctor) {
            esignDoctor.setSealImage(SealImageUtil.setSealImage(sealImgPath));
            esignDoctor.setChangedAt(new Date());
            recomEsignDoctorRepository.update(esignDoctor);
        }
    }

    @Override
    public void setAuthStatus(Long doctorId, Integer status) {
        EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (null != esignDoctor) {
            esignDoctor.setAuthStatus(status);
            esignDoctor.setChangedAt(new Date());
            recomEsignDoctorRepository.update(esignDoctor);
        }
    }

    @Override
    public Boolean getSignAccountByDoctorIdAndIdNo(Long doctorId, String number) {
        EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByDoctorIdAndIdCard(doctorId, number);
        return esignDoctor == null ? false : true;
    }

    @Override
    public DigitalCertificateBO getDigitalCertificate(Long doctorId) throws BusinessException {
        EsignDoctor esignDoctor = recomEsignDoctorRepository.findFirstByDoctorId(doctorId);
        if (null == esignDoctor) {
            throw new BusinessException(ExceptionCodes.ESIGN_DOCTOR_USER_NOT_EXISTS);
        }
        // 获取激活厂商
        EsignServiceProviderEnum service = signService.getCurrentServiceProvider();
        if (EsignServiceProviderEnum.ESIGN_WUKONG_SDK.equals(service)) {
            return DigitalCertificateBO.builder().username(esignDoctor.getName())
                .idCard(IdcardUtil.hide(esignDoctor.getIdCard(), 7, 15)).issuingAuthority("杭州天谷信息科技有限公司")
                .sealCertNumber(StrUtil.hide(esignDoctor.getOpenId(), 7, 25))
                .issuingTime(DateUtil.formatDate(esignDoctor.getCreatedAt(), DateUtil.DATE_FORMAT_CN)).validUntil("永久")
                .build();
        }
        if (EsignServiceProviderEnum.SCCA.equals(service)) {
            String openId = esignDoctor.getOpenId();
            EsignSccaCert sccaCert = esignSccaCertRepository.findByOpenId(openId);
            return DigitalCertificateBO.builder().username(esignDoctor.getName())
                .idCard(IdcardUtil.hide(esignDoctor.getIdCard(), 7, 15)).issuingAuthority("四川省数字证书认证管理中心有限公司")
                .sealCertNumber(StrUtil.hide(sccaCert.getCertSerialnumber(), 7, 25))
                .issuingTime(DateUtil.formatDate(esignDoctor.getCreatedAt(), DateUtil.DATE_FORMAT_CN))
                .validUntil(DateUtil.formatDate(sccaCert.getNotAfter(), DateUtil.DATE_FORMAT_CN)).build();
        }
        return DigitalCertificateBO.builder().username(esignDoctor.getName())
            .idCard(IdcardUtil.hide(esignDoctor.getIdCard(), 7, 15)).build();
    }

    @Override
    public EsignDoctorBO getAccountByIdNoAndAuthStatus(String idNo, Integer authStatus) {
        EsignDoctor doctor = recomEsignDoctorRepository.findFirstByIdCardAndAuthStatus(idNo, authStatus);
        if(doctor == null){
            return null;
        }
        EsignDoctorBO bo = new EsignDoctorBO();
        BeanUtil.copyProperties(doctor, bo);
        bo.setSealImage(ConfigUtil.getString("ehp.domain.img") + bo.getSealImage());
        return bo;
    }

    @Override
    public void checkDoctorRealname(String idCard) throws BusinessException {
        EsignPharmacist esignPharmacist =
            recomEsignPharmacistRepository.findFirstByIdCardAndAuthStatus(idCard, EsignPharmacist.AUTH_STATUS_PASS);
        if (esignPharmacist != null) {
            throw new BusinessException(ExceptionCodes.ESIGN_AUTH_IDCARD_EXISTS);
        }
    }

}
